package com.api.common.log;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.api.common.exception.ParamException;
import com.api.common.reqres.ReqResConstant;
import com.api.common.reqres.Response;
import com.api.component.DateComponent;
import com.api.component.HttpComponent;
import com.api.component.ResponseComponent;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Aspect
@Component
public class SystemLogAspect {
	@Autowired
	private HttpComponent httpComponent;
	@Autowired
	private DateComponent dateComponent;
	@Autowired
	private ResponseComponent responseComponent;

	/**
	 * 环切，请求数据库记录
	 * 
	 * @param pjp
	 * @return
	 */
	@Around("execution(* com.api.mapper.*.*(..))")
	public Object handleMapper(ProceedingJoinPoint pjp) {
		long start = System.currentTimeMillis();
		Signature signature = pjp.getSignature();
		String className = signature.getDeclaringTypeName();
		String methodName = signature.getName();
		try {
			return pjp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
			log.error(e.getMessage());
			throw new RuntimeException(e);
		} finally {
			long end = System.currentTimeMillis();
			long usertime = end - start;
			log.info("className:" + className + "-methodName:" + methodName + "-用时:" + usertime);
		}
	}

	/**
	 * 环切，打印请求返回日志
	 * 
	 * @param pjp
	 * @return
	 */
	@Around("execution(* com.api.controller.*.*(..))")
	public Object handleController(ProceedingJoinPoint pjp) {
		long start = System.currentTimeMillis();
		Signature signature = pjp.getSignature();
		String className = signature.getDeclaringTypeName();
		String methodName = signature.getName();
		SystemLog systemLog = new SystemLog();
		systemLog.setClassName(className);
		systemLog.setMethodName(methodName);
		systemLog.setReqtime(dateComponent.getDateyyyyMMddHHmmssSSSOne());
		systemLog.setReqip(httpComponent.getIpAddress());
		// 请求的参数
		Object[] args = pjp.getArgs();
		// 将参数所在的数组转换成json
		String reqstr = JSON.toJSONString(args, SerializerFeature.WriteMapNullValue);
		systemLog.setReqstr(reqstr);
		String resstr = null;
		try {
			Object result = pjp.proceed();
			resstr = JSON.toJSONString(result, SerializerFeature.WriteMapNullValue);
			return result;
		} catch (ParamException e) {
//			e.printStackTrace();
//			log.error(e.getMessage());
			Response response = responseComponent.toError(e.getMessage());
			resstr = JSON.toJSONString(response);
			return response;
		} catch (Throwable e) {
			e.printStackTrace();
			log.error(e.getMessage());
			Response response = responseComponent.toError(ReqResConstant.ERROR_SYSTEM_CODE,
					ReqResConstant.ERROR_SYSTEM_MSG);
			resstr = JSON.toJSONString(response);
			return response;
		} finally {
			systemLog.setResstr(resstr);
			systemLog.setRestime(dateComponent.getDateyyyyMMddHHmmssSSSOne());
			long end = System.currentTimeMillis();
			long usertime = end - start;
			systemLog.setUsetime(usertime);
			log.info(JSON.toJSONString(systemLog, SerializerFeature.WriteMapNullValue));
		}
	}
}
